﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;

using Lenovo.CFI.Common;
using Lenovo.CFI.DAL;
using Lenovo.CFI.BLL.Mail;
using Lenovo.CFI.Common.Dic;
using Lenovo.CFI.Common.Sys;
using Lenovo.CFI.DAL.Sys;
using Lenovo.CFI.BLL.DicMgr;

namespace Lenovo.CFI.BLL
{
    public class ReviewBl
    {
        // 何时更新 Idea的Final状态
        // Suggestion 由DC确定，助理启动Exe？以后即时更新

        // 何时更新Idea的状态
        // 第一次评审的，即时更新 == Review Topic ID = current id ？？
        // 再次评审的，也即时更新？-- 从启动评审开始

        // 确定参与评审，那么更新Review Topic ID and Review ID
        // 但是对于再次评审的？同理

        public List<IdeaReview> GetReview(int topicID)
        {
            return ReviewDa.GetReview(topicID);
        }

        public IdeaReview GetReviewByID(int id)
        {
            return ReviewDa.GetReviewByID(id);
        }

        public List<IdeaReview> GetReviewByIDs(List<int> ids)
        {
            return ReviewDa.GetReviewByIDs(ids);
        }


        public List<IdeaReview> GetReviewForDcOwner(int? topicID, string dcOwner)
        {
            return ReviewDa.GetReview(topicID, null, null, dcOwner, null, null);
        }

        public List<IdeaReview> GetReviewForIpOwner(int? topicID, string ipOwner)
        {
            return ReviewDa.GetReview(topicID, null, null, null, ipOwner, null);
        }

        public List<IdeaReview> GetReviewForExecutor(int? topicID, string executor)
        {
            return ReviewDa.GetReview(topicID, null, null, null, null, executor);
        }


        public List<IdeaReviewDetail> GetReviewDetail(int reviewID)
        {
            return ReviewDa.GetReviewDetail(null, reviewID, null, null, null);
        }

        public List<IdeaReviewDetail> GetReviewDetail(int topicID, string reviewer)
        {
            return ReviewDa.GetReviewDetail(topicID, null, reviewer, null, null);
        }

        public IdeaReviewDetail GetReviewDetailByID(int id)
        {
            return ReviewDa.GetReviewDetailByID(id);
        }







        public void OwnerConfirm(int id, bool confirm, string comment)
        {
            IdeaReview review = ReviewDa.GetReviewByID(id);
            review.OwnerConfirmed = confirm;
            review.OwnerConfirmComment = comment;

            ReviewDa.UpdateReview(review);
        }

        public void Record(int id, string reviewType, IdeaReviewStatus status, string record)
        {
            IdeaReview review = ReviewDa.GetReviewByID(id);

            bool start = false;
            if (status == IdeaReviewStatus.OnGoing && review.ReviewStatus == IdeaReviewStatus.Waiting)
                start = true;

            review.ReviewType = reviewType;
            review.ReviewStatus = status;
            review.ReviewRecord = record;


            // 存储
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    ReviewDa.UpdateReview(review, trans);

                    if (start) ReviewDa.UpdateReviewOngoing(id, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

        }

        public void Review(int reviewID, string reviewer, string agent, 
            decimal? cv, decimal? bv, decimal? tv, string type, string typeComment, 
            int? ip, string ipComment, string suggestion, string note)
        {
            IdeaReviewDetail detail = ReviewDa.GetReviewDetailByReviewer(reviewID, reviewer);

            if (detail != null)
            {
                if (detail.Finished) return;

                detail.Agent = agent;
                if (cv.HasValue) detail.Cv = (cv < 0 ? null : cv);
                if (bv.HasValue) detail.Bv = (bv < 0 ? null : bv);
                if (tv.HasValue) detail.Tv = (tv < 0 ? null : tv);
                if (type != null) detail.Type = (type == String.Empty) ? null : type;
                if (typeComment != null) detail.TypeComment = (typeComment == String.Empty) ? null : typeComment;
                if (ip.HasValue) detail.Ip = (ip < 0 ? (bool?)null : (ip == 1));
                if (ipComment != null) detail.IpComment = (ipComment == String.Empty) ? null : ipComment;
                if (suggestion != null) detail.Suggestion = (suggestion == String.Empty) ? null : suggestion;
                if (note != null) detail.Note = (note == String.Empty) ? null : note;

                detail.Stamp = DBHelper.GetNowForDB();

                ReviewDa.UpdateReviewDetail(detail);
            }
            else
            {
                detail = new IdeaReviewDetail(reviewID);
                detail.Reviewer = reviewer;
                detail.Agent = agent;
                detail.Finished = false;

                if (cv.HasValue) detail.Cv = (cv < 0 ? null : cv);
                if (bv.HasValue) detail.Bv = (bv < 0 ? null : bv);
                if (tv.HasValue) detail.Tv = (tv < 0 ? null : tv);
                if (type != null) detail.Type = (type == String.Empty) ? null : type;
                if (typeComment != null) detail.TypeComment = (typeComment == String.Empty) ? null : typeComment;
                if (ip.HasValue) detail.Ip = (ip < 0 ? (bool?)null : (ip == 1)); ;
                if (ipComment != null) detail.IpComment = (ipComment == String.Empty) ? null : ipComment;
                if (suggestion != null) detail.Suggestion = (suggestion == String.Empty) ? null : suggestion;
                if (note != null) detail.Note = (note == String.Empty) ? null : note;

                detail.Stamp = DBHelper.GetNowForDB();

                ReviewDa.InsertReviewDetail(detail);
            }

        }

        public void Finish(int topicID, string reviewer)
        {
            List<IdeaReviewDetail> details = ReviewDa.GetReviewDetail(topicID, null, reviewer, null, null);

            // 存储
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    foreach (IdeaReviewDetail detail in details)
                    {
                        if (!detail.Finished)
                        {
                            if (detail.Cv.HasValue && detail.Bv.HasValue && detail.Tv.HasValue)
                            {
                                detail.Finished = true;
                                detail.Stamp = DBHelper.GetNowForDB();

                                ReviewDa.UpdateReviewDetail(detail, trans);
                            }
                            else
                            {
                                ReviewDa.DeleteReviewDetail(detail.ID, trans);
                            }
                        }
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        public void Remind(int topicID, string reviewer)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);

            new MailBl().MailSubmitReviewResult(topic.Title, reviewer);
        }

        public void Summary(int reviewID, string reviewType, bool reviewIP, string summary, decimal score)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);

            review.ReviewType = reviewType;
            review.ReviewIP = reviewIP;
            //review.ReviewScore = score;
            review.ReviewSummary = summary;
            review.ReviewStatus = IdeaReviewStatus.Summary;     // 已经进行了Summary

            ReviewDa.UpdateReview(review);
        }

        public void ResetType(int reviewID, string reviewType)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);

            review.ReviewType = reviewType;
            review.ActionExecutor = TopicDa.GetTopicDcIp(review.TopicID, null, reviewType, null)[0].User;
            review.DcConfirmed = 0;

            ReviewDa.UpdateReview(review);
        }

        public void Award(int reviewID, int? award, string awardComment, string actionExecutor)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);
            Idea idea = IdeaDa.GetByID(review.IdeaID);

            if (actionExecutor == String.Empty) actionExecutor = null;

            review.Award = award;
            review.AwardComment = awardComment;
            //review.ActionExecutor = actionExecutor;

            idea.FinalAward = award;

            // 存储
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    ReviewDa.UpdateReview(review, trans);

                    IdeaDa.UpdateIdea(idea, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        public void DcSuggest(int reviewID, SuggestionStatus status, string nextAction, string nextActionBU, string executor, 
            int level, string keyword1, string keyword2, string keyword3, string freeKeywords)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);

            if (status == SuggestionStatus.OnGoing)
            {
                if (review.DcConfirmed == SuggestionStatus.Reject || review.DcConfirmed == SuggestionStatus.Finished) throw new BusinessObjectLogicException("Invalid operation!");

                review.DcConfirmed = status;
                review.NextActionPrev = review.NextAction;
                review.NextAction = String.IsNullOrEmpty(nextAction) ? null : nextAction;
                if (review.NextAction == NextAction.OTHERBU)
                {
                    review.NextActionBu = String.IsNullOrEmpty(nextActionBU) ? null : nextActionBU;

                    if (review.NextActionBu != null)
                        review.ActionExecutor = OtherBuDicMgr.dicMgr.GetEntry(review.NextActionBu).Executor;
                }
                else
                {
                    review.NextActionBu = null;
                    review.ActionExecutor = String.IsNullOrEmpty(executor) ? null : executor;
                }

                Idea idea = IdeaDa.GetByID(review.IdeaID);
                idea.SecretLevel = level;
                List<string> kws = new List<string>();
                if (!String.IsNullOrEmpty(keyword1)) kws.Add(keyword1);
                if (!String.IsNullOrEmpty(keyword2)) kws.Add(keyword2);
                if (!String.IsNullOrEmpty(keyword3)) kws.Add(keyword3);
                idea.Keywords = CodeList.CreateByList(kws.ToArray());

                // 存储
                using (TranscationHelper trans = TranscationHelper.GetInstance())
                {
                    trans.BeginTrans();
                    try
                    {
                        ReviewDa.UpdateReview(review, trans);

                        IdeaDa.UpdateIdea(idea, trans);

                        trans.CommitTrans();
                    }
                    catch
                    {
                        trans.RollTrans();
                        throw;
                    }
                }
            }
            else if (status == SuggestionStatus.Reject)
            {
                if (review.DcConfirmed != SuggestionStatus.None) throw new BusinessObjectLogicException("Invalid operation!");

                review.DcConfirmed = status;

                ReviewDa.UpdateReview(review);

                Idea idea = IdeaDa.GetByID(review.IdeaID);
                List<User> assistants = UserDa.GetUserWithRole(UserRole.ROLE_ASSISTANT1);

                //发送邮件
                new MailBl().MailSuggestDcReject(idea.Title, review.DcOwner, MailBl.ConvertMailAddress(assistants));
            }
            else if (status == SuggestionStatus.Finished)
            {
                if (review.DcConfirmed == SuggestionStatus.Finished) throw new BusinessObjectLogicException("Invalid operation!");

                review.DcConfirmed = status;
                review.NextActionPrev = review.NextAction;
                review.NextAction = String.IsNullOrEmpty(nextAction) ? null : nextAction;
                if (review.NextAction == null) throw new BusinessObjectLogicException("Invalid next action!");
                if (review.NextAction == NextAction.OTHERBU)
                {
                    review.NextActionBu = String.IsNullOrEmpty(nextActionBU) ? null : nextActionBU;
                    if (review.NextActionBu == null) throw new BusinessObjectLogicException("Invalid next action BU!");

                    review.ActionExecutor = OtherBuDicMgr.dicMgr.GetEntry(review.NextActionBu).Executor;
                }
                else
                {
                    review.NextActionBu = null;
                    review.ActionExecutor = String.IsNullOrEmpty(executor) ? null : executor;
                }
                if (review.NextAction == NextAction.MKT ||
                    review.NextAction == NextAction.NEXTROUND ||
                    review.NextAction == NextAction.TBD) review.ActionExecutor = null; // 无执行人
                else if (review.ActionExecutor == null) throw new BusinessObjectLogicException("Invalid next action executor!");
                review.ActionStatus = ExecutionStatus.None; // 无执行状态

                Idea idea = IdeaDa.GetByID(review.IdeaID);
                idea.SecretLevel = level;
                List<string> kws = new List<string>();
                if (!String.IsNullOrEmpty(keyword1)) kws.Add(keyword1);
                if (!String.IsNullOrEmpty(keyword2)) kws.Add(keyword2);
                if (!String.IsNullOrEmpty(keyword3)) kws.Add(keyword3);
                idea.Keywords = CodeList.CreateByList(kws.ToArray());


                idea.FinalType = review.ReviewType;
                idea.FinalAction = review.NextAction;
                idea.FinalActionBU = review.NextActionBu;
                idea.FinalActionStatus = review.ActionStatus;

                if (review.NextAction == NextAction.MKT ||
                    review.NextAction == NextAction.NEXTROUND ||
                    review.NextAction == NextAction.TBD)
                {
                    if (review.IPConfirmed == SuggestionStatus.Finished && review.NextIP == false)
                        idea.Status = IdeaStatus.Closed;    // 结束
                    else
                        idea.Status = IdeaStatus.Execution; // 开始执行
                }
                else
                    idea.Status = IdeaStatus.Execution; // 开始执行
                idea.CanSearch = true;

                // 存储
                using (TranscationHelper trans = TranscationHelper.GetInstance())
                {
                    trans.BeginTrans();
                    try
                    {
                        ReviewDa.UpdateReview(review, trans);

                        IdeaDa.UpdateIdea(idea, trans);

                        trans.CommitTrans();
                    }
                    catch
                    {
                        trans.RollTrans();
                        throw;
                    }
                }

                //发送邮件
                User user = UserDa.GetUserByItCode(review.ActionExecutor);
                new MailBl().MailSuggestDcFinish(idea.Title, review.DcOwner, NextActionDicMgr.dicMgr.GetTitle(review.NextAction),
                    MailBl.ConvertMailAddress(user.ItCode, user.Manager, review.DcOwner));
            }
            else
                throw new BusinessObjectLogicException("Invalid operation!");
        }

        public void DcNoticeMail(int reviewID, string mailContent)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);
            Idea idea = IdeaDa.GetByID(review.IdeaID);

            new MailBl().MailSuggestDcNotice(idea.Title, review.DcOwner, review.NextAction,
                MailBl.ConvertMailAddress(idea.Owner), mailContent);
        }

        public void IpSuggest(int reviewID, SuggestionStatus status, bool nextIP, string executor)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);

            if (status == SuggestionStatus.OnGoing)
            {
                if (review.IPConfirmed == SuggestionStatus.Reject || review.IPConfirmed == SuggestionStatus.Finished) throw new BusinessObjectLogicException("Invalid operation!");

                review.IPConfirmed = status;
                review.NextIP = nextIP;
                review.IpExecutor = String.IsNullOrEmpty(executor) ? null : executor;

                ReviewDa.UpdateReview(review);
            }
            else if (status == SuggestionStatus.Finished)
            {
                if (review.IPConfirmed == SuggestionStatus.Finished) throw new BusinessObjectLogicException("Invalid operation!");

                review.IPConfirmed = status;
                review.NextIP = nextIP;
                review.IpExecutor = String.IsNullOrEmpty(executor) ? null : executor;
                if (!review.NextIP.Value) review.IpExecutor = null; // 无执行人
                else if (review.IpExecutor == null) throw new BusinessObjectLogicException("Invalid ip executor!");
                review.IpStatus = ExecutionStatus.None;

                Idea idea = IdeaDa.GetByID(review.IdeaID);

                idea.Status = IdeaStatus.Execution; // 开始执行
                idea.FinalIP = review.NextIP;


                if (review.NextIP == false)
                {
                    if (review.NextAction == NextAction.MKT ||
                       review.NextAction == NextAction.NEXTROUND ||
                       review.NextAction == NextAction.TBD)
                    {
                        idea.Status = IdeaStatus.Closed;    // 结束
                    }
                    else
                        idea.Status = IdeaStatus.Execution; // 开始执行
                }
                else
                    idea.Status = IdeaStatus.Execution; // 开始执行
                idea.CanSearch = true;

                // 存储
                using (TranscationHelper trans = TranscationHelper.GetInstance())
                {
                    trans.BeginTrans();
                    try
                    {
                        ReviewDa.UpdateReview(review, trans);

                        IdeaDa.UpdateIdea(idea, trans);

                        trans.CommitTrans();
                    }
                    catch
                    {
                        trans.RollTrans();
                        throw;
                    }
                }

                //发送邮件
                User user = UserDa.GetUserByItCode(review.IpExecutor);
                new MailBl().MailSuggestIpFinish(idea.Title, review.DcOwner, 
                    MailBl.ConvertMailAddress(user.ItCode, user.Manager, review.DcOwner));
            }
            else
                throw new BusinessObjectLogicException("Invalid operation!");
        }


        public void ExecuteAction(int reviewID, ExecutionStatus status, string name, DateTime? time, string otherBuNextAction, string comment)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);
            Idea idea = IdeaDa.GetByID(review.IdeaID);

            if (review.NextAction == NextAction.OTHERBU)
                review.OtherBuNextAction = otherBuNextAction;
            else
            {
                review.ProjectName = name;
                review.ProjectTime = time;
            }
            review.ActionComment = comment;
            review.ActionStatus = status;

            idea.FinalActionStatus = review.ActionStatus;

            if (status == ExecutionStatus.Preparing || status == ExecutionStatus.OnGoing)
            {
                
            }
            else
            {
                if (review.IpExecutor == null || review.IpStatus == ExecutionStatus.Finished || review.IpStatus == ExecutionStatus.Canceled)
                {
                    idea.Status = IdeaStatus.Closed;        // close
                }
            }


            // 存储
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    ReviewDa.UpdateReview(review, trans);

                    IdeaDa.UpdateIdea(idea, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        public void ExecuteIP(int reviewID, ExecutionStatus status, string no, string comment)
        {
            IdeaReview review = ReviewDa.GetReviewByID(reviewID);
            Idea idea = IdeaDa.GetByID(review.IdeaID);

            review.IpNo = no;
            review.IpComment = comment;
            review.IpStatus = status;

            idea.FinalIPStatus = review.IpStatus;

            if (status == ExecutionStatus.Preparing || status == ExecutionStatus.OnGoing)
            {

            }
            else
            {
                if (review.ActionExecutor == null || review.ActionStatus == ExecutionStatus.Finished || review.ActionStatus == ExecutionStatus.Canceled)
                {
                    idea.Status = IdeaStatus.Closed;        // close
                }
            }


            // 存储
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    ReviewDa.UpdateReview(review, trans);

                    IdeaDa.UpdateIdea(idea, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

    }
}
